#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: liang kang
@contact: gangkanli1219@gmail.com
@time: 12/29/17 12:18 PM
@desc: revolve the image to create data
"""
import numpy as np

from utils.revolver import Revolver
from utils.basic import is_in_rect


class CrowdCountingRevolver(Revolver):
    """
    按一定角度旋转图像并切割为子图，并获取其对应的人物坐标点
    """

    def __init__(self, image_path, points, revolve_angle=10, params=None):
        """
        初始化

        Parameters
        ----------
        image_path
        points
        revolve_angle
        params
        """
        super(CrowdCountingRevolver, self).__init__(image_path, revolve_angle, params)

        # 点坐标最后加一，方便旋转
        self._points = list(map(lambda x: x + [1.0], points))
        self._points = np.matrix(self._points)[:, (1, 0, 2)]
        self._revolved_points = None
        self._revolve_mat = None

    @property
    def revolve_mat(self):
        return self._revolve_mat

    def _get_revolve_mat(self):
        """
        compute the revolve matrix

        Returns
        -------

        """
        angle = self.angle * np.pi / 180
        revolve_mat_1 = np.matrix([[1, 0, 0], [0, -1, 0],
                                   [-0.5 * self.image_size[1], 0.5 * self.image_size[0], 1]])
        revolve_mat_2 = np.matrix([[np.cos(angle), np.sin(angle), 0],
                                   [- np.sin(angle), np.cos(angle), 0], [0, 0, 1]])
        revolve_mat_3 = np.matrix([[1, 0, 0], [0, -1, 0],
                                   [0.5 * self.revolved_image_size[1],
                                    0.5 * self.revolved_image_size[0], 1]])
        self._revolve_mat = revolve_mat_1 * revolve_mat_2 * revolve_mat_3

    def _crop_process(self):
        """

        Returns
        -------

        """
        seat = self.info['other']['seat']
        size = self.info['other']['size']
        points_in_cropped_image = []
        img_rect = [seat[0], seat[1], seat[0] + size[0], seat[1] + size[1]]
        for point in self._revolved_points.tolist():
            if is_in_rect(point, img_rect):
                points_in_cropped_image.append([(point[0] - seat[0]) / size[0],
                                                (point[1] - seat[1]) / size[1]])
        self.info['point'] = points_in_cropped_image

    def _process_angle(self):
        """

        Returns
        -------

        """
        self._get_revolve_mat()
        self._revolved_points = self._points * self._revolve_mat
        self._revolved_points = self._revolved_points[:, (1, 0)]
        d = list(map(lambda x, y: (x - y) // 2, self.revolved_image_size, self.image_size))
        self._revolved_points[:, 0] -= d[0]
        self._revolved_points[:, 1] -= d[1]
